package com.yykj.tencent.im.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yykj.common.service.RedisService;
import com.yykj.common.util.PageRequestUtil;
import com.yykj.common.vo.PageData;
import com.yykj.tencent.im.client.constant.TagProfile;
import com.yykj.tencent.im.client.form.QueryMsgDto;
import com.yykj.tencent.im.client.form.QueryMsgForm;
import com.yykj.tencent.im.server.bean.request.ProfileItem;
import com.yykj.tencent.im.server.bean.response.PortraitGetResult;
import com.yykj.tencent.im.server.bean.response.UserProfileItem;
import com.yykj.tencent.im.server.core.TimUtil;
import com.yykj.tencent.im.server.enums.MsgType;
import com.yykj.tencent.im.server.model.entity.Message;
import com.yykj.tencent.im.server.model.repository.MessageRepository;
import com.yykj.tencent.im.server.service.AccountService;
import com.yykj.tencent.im.server.service.GroupService;
import com.yykj.tencent.im.server.service.ImService;
import com.yykj.tencent.im.server.service.TpnsService;
import com.yykj.tencent.im.server.utils.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
@Slf4j
public class ImServiceImpl implements ImService {
    @Value("${environment}")
    private String environment;
    @Autowired
    MessageRepository messageRepository;

    @Resource
    private AccountService accountService;

    @Resource
    private RedisService redisService;

    @Autowired
    GroupService groupService;
    @Autowired
    TpnsService tpnsService;
    @Override
    public String getUserSig() {
        return TimUtil.getUserSig();
    }

    @Override
    public PageData<QueryMsgDto> queryMsg(QueryMsgForm queryMsgForm) {
        int messsageType = queryMsgForm.getMesssageType();
        if(messsageType == 0){//单聊
            if(StringUtils.isBlank(queryMsgForm.getToAccount())){
                throw new RuntimeException("单聊消息 接收人帐号不能为空");
            }
            if(StringUtils.isBlank(queryMsgForm.getFromAccount())){
                throw new RuntimeException("单聊消息 发送人帐号不能为空");
            }
        }else{
            if(StringUtils.isBlank(queryMsgForm.getGroupId())){
                throw new RuntimeException("群聊消息 群组ID不能为空");
            }
            if(!"meeting".equals(queryMsgForm.getGroupType()) && queryMsgForm.getStartTime() == 0){
                throw new RuntimeException("非meeting类型的群聊 startTime必填");
            }
        }

        Pageable page = PageRequest.of(PageRequestUtil.getPage(queryMsgForm.getPageNum())
                ,PageRequestUtil.getSize(queryMsgForm.getPageSize())
                , Sort.by(Sort.Direction.ASC, "msgTime"));
        Page<Message> list = messageRepository.findAll(new Specification<Message>(){
            @Override
            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                List<Predicate> predicateList = new ArrayList<>();
                if(messsageType == 0){//单聊 查双方的
                    Predicate p1 = builder.equal(root.get("fromAccount"),queryMsgForm.getFromAccount());
                    Predicate p2 = builder.equal(root.get("toAccount"),queryMsgForm.getToAccount());
                    Predicate b1 = builder.and(p1, p2);
                    Predicate p3 = builder.equal(root.get("fromAccount"),queryMsgForm.getToAccount());
                    Predicate p4 = builder.equal(root.get("toAccount"),queryMsgForm.getFromAccount());
                    Predicate b2 = builder.and(p3, p4);
                    predicateList.add(builder.or(b1, b2));

                }else{
                    if(StringUtils.isNotBlank(queryMsgForm.getFromAccount())){
                        predicateList.add(builder.equal(root.get("fromAccount"),queryMsgForm.getFromAccount()));
                    }
                    predicateList.add(builder.equal(root.get("groupId"),queryMsgForm.getGroupId()));
                    if(!"meeting".equals(queryMsgForm.getGroupType())){
                        predicateList.add(builder.ge(root.get("msgTime"),queryMsgForm.getStartTime()));
                    }
                }
                if(queryMsgForm.getMsgType() != 0){
                    if(queryMsgForm.getMsgType() == 6){//视频和图片一起查
                        Predicate p1 = builder.equal(root.get("msgType"), MsgType.TIMImageElem.getType());
                        Predicate p2 = builder.equal(root.get("msgType"), MsgType.TIMVideoFileElem.getType());
                        predicateList.add(builder.or(p1, p2));
                    }else{
                        predicateList.add(builder.equal(root.get("msgType"),queryMsgForm.getMsgType()));
                    }

                }
                if (StringUtils.isNotBlank(queryMsgForm.getMsgTime())) {
                    int startTime = SignUtil.date2TimeStamp(queryMsgForm.getMsgTime(), "yyyy-MM-dd");
                    int endTime = startTime + 86400;
                    predicateList.add(builder.greaterThan(root.get("msgTime"), startTime));
                    predicateList.add(builder.lessThan(root.get("msgTime"), endTime));
                }

                if(StringUtils.isNotBlank(queryMsgForm.getKeyword())){
                    predicateList.add(builder.like(root.get("content"),"%" + queryMsgForm.getKeyword() + "%"));
                }
                Predicate[] predicates = new Predicate[predicateList.size()];
                return query.where(predicateList.toArray(predicates)).getRestriction();
            }
        },page);

        PageData<QueryMsgDto> result = new PageData<>();
        ArrayList<QueryMsgDto> queryGroupMsgDtos = new ArrayList<>();
        Iterator<Message> iterator = list.iterator();
        while(iterator.hasNext()){
            Message next = iterator.next();
            QueryMsgDto queryGroupMsgDto = new QueryMsgDto();
            BeanUtils.copyProperties(next,queryGroupMsgDto);
            queryGroupMsgDtos.add(queryGroupMsgDto);
        }
        result.setCurrentPage(queryMsgForm.getPageNum());
        result.setPageSize(queryMsgForm.getPageSize());
        result.setTotalPage(list.getTotalPages());
        result.setTotalCount(list.getTotalElements());
        result.setList(queryGroupMsgDtos);
        return result;
    }

    @Async
    @Override
    public void addMessage(String json, int messageType) {
        //messageType 0:单聊,1:群聊
        JSONObject messageJson = JSON.parseObject(json);
        JSONArray msgBody = messageJson.getJSONArray("MsgBody");
        if(msgBody != null && msgBody.size() > 0){
            JSONObject msgBodyChild = msgBody.getJSONObject(0);
            String fromAccount = messageJson.getString("From_Account");
            String toAccount = messageJson.getString("To_Account");
            String operatorAccount = messageJson.getString("Operator_Account");
            String groupId = messageJson.getString("GroupId");
            String msgSeq = messageJson.getString("MsgSeq");
            String msgKey = messageJson.getString("MsgKey");
            String groupType = messageJson.getString("Type");
            int msgTime = messageJson.getInteger("MsgTime");
            String msgBodyJson = JSON.toJSONString(msgBody);
            Message message = Message.builder()
                    .environment(environment)
                    .fromAccount(fromAccount)
                    .groupId(groupId)
                    .operatorAccount(operatorAccount)
                    .toAccount(toAccount)
                    .msgTime(msgTime)
                    .messsageType(messageType)
                    .groupType(groupType)
                    .msgSeq(msgSeq)
                    .msgBody(msgBodyJson)
                    .msgKey(msgKey).build();
            String msgType = msgBodyChild.getString("MsgType");
            JSONObject msgContent = msgBodyChild.getJSONObject("MsgContent");
            message.setMsgType(MsgType.valueOf(msgType).getType());
            //获取 帐号名字头像信息
            ArrayList<String> imIds = new ArrayList<>();
            if(StringUtils.isNotBlank(fromAccount)){
                imIds.add(fromAccount);
            }
            if(StringUtils.isNotBlank(toAccount)){
                imIds.add(toAccount);
            }
            if(StringUtils.isNotBlank(operatorAccount)){
                imIds.add(operatorAccount);
            }
            String fromAccountName = "";
            String fromAccountAvatar = "";
            String toAccountName = "";
            String toAccountAvatar = "";
            String operatorAccountName = "";
            String operatorAccountAvatar = "";
            String tpnsTitle = "收到一条新消息";
            String tpnsContent = "";
            PortraitGetResult portraitGetResult = this.accountService.portraitGet(imIds);
            if(portraitGetResult != null){
                List<UserProfileItem> userProfileItemList = portraitGetResult.getUserProfileItemList();
                if(userProfileItemList != null && userProfileItemList.size() > 0){
                    for(UserProfileItem userProfileItem : userProfileItemList){
                        List<ProfileItem> profileItemList = userProfileItem.getProfileItemList();
                        if(profileItemList != null && profileItemList.size() > 0){
                            String account = userProfileItem.getToAccount();
                            String username = "";
                            String avatar = "";
                            for(ProfileItem profileItem : profileItemList){
                                String value = profileItem.getValue();
                                String tag = profileItem.getTag();
                                if(TagProfile.IM_NICK.equals(tag)){
                                    username = value;
                                }else if(TagProfile.IM_IMAGE.equals(tag)){
                                    avatar = value;
                                }
                            }
                            if(account.equals(fromAccount)){
                                fromAccountName = username;
                                fromAccountAvatar = avatar;
                            }else if(account.equals(toAccount)){
                                toAccountName = username;
                                toAccountAvatar = avatar;
                            }else if(account.equals(operatorAccount)){
                                operatorAccountName = username;
                                operatorAccountAvatar = avatar;
                            }
                        }
                    }
                }
            }

            message.setFromAccountName(fromAccountName);
            message.setFromAccountAvatar(fromAccountAvatar);
            message.setToAccountName(toAccountName);
            message.setToAccountAvatar(toAccountAvatar);
            message.setOperatorAccountName(operatorAccountName);
            message.setOperatorAccountAvatar(operatorAccountAvatar);
            switch (msgType){
                //文本
                case "TIMTextElem":
                    String text = msgContent.getString("Text");
                    tpnsTitle = fromAccountName;
                    tpnsContent = text;
                    message.setContent(text);
                    break;
                //图片
                case "TIMImageElem":
                    tpnsTitle = "[图片]";
                    JSONArray imageInfoArray = msgContent.getJSONArray("ImageInfoArray");
                    if(imageInfoArray != null && imageInfoArray.size() > 0){
                        String size = "";
                        String url = "";
                        String thumbnailImageUrl = "";
                        for(int i = 0; i < imageInfoArray.size(); i++){
                            JSONObject imageInfoObject = imageInfoArray.getJSONObject(i);
                            Integer type = imageInfoObject.getInteger("Type");
                            if(type == 1){//原图
                                size = imageInfoObject.getString("Size");
                                url = imageInfoObject.getString("URL");
                            }else if (type == 3){//缩略图
                                thumbnailImageUrl = imageInfoObject.getString("URL");
                            }
                        }
                        message.setSize(size);
                        message.setUrl(url);
                        message.setThumbnailImageUrl(thumbnailImageUrl);
                    }
                    break;
               //音频
                case "TIMSoundElem":
                    tpnsTitle = "[语音]";
                    /*String second = msgContent.getString("Second");
                    String size = msgContent.getString("Size");
                    String Url = msgContent.getString("Url");
                    message.setSize(size);
                    message.setUrl(Url);
                    message.setSecond(second);*/
                    break;
                //视频
                case "TIMVideoFileElem":
                    tpnsTitle = "[视频]";
                    String videoSize = msgContent.getString("VideoSize");
                    String videoSecond = msgContent.getString("VideoSecond");
                    String videoUrl = msgContent.getString("VideoUrl");
                    String thumbUrl = msgContent.getString("ThumbUrl");
                    message.setSize(videoSize);
                    message.setUrl(videoUrl);
                    message.setSecond(videoSecond);
                    message.setThumbnailImageUrl(thumbUrl);
                    break;

                //文件
                case "TIMFileElem":
                    tpnsTitle = "[文件]";
                    String fileName = msgContent.getString("FileName");
                    String fileSize = msgContent.getString("FileSize");
                    String url = msgContent.getString("Url");
                    message.setSize(fileSize);
                    message.setUrl(url);
                    message.setContent(fileName);
                    break;
            }

            /*//tpns
            HashSet<String> accountList = new HashSet<>();
            if(messageType == 1){//群聊 查询群里所有人
                GetGroupMemberInfoRequest getGroupMemberInfoRequest = GetGroupMemberInfoRequest.builder()
                        .groupId(groupId)
                        .offset(0)
                        .limit(100).build();
                GetGroupMemberInfoResult groupMemberInfo = this.groupService.getGroupMemberInfo(getGroupMemberInfoRequest);
                if(groupMemberInfo != null){
                    List<MemberProfile> memberList = groupMemberInfo.getMemberList();
                    memberList.forEach(item -> {
                        if(!item.getMemberAccount().equals(fromAccount)){
                            accountList.add(item.getMemberAccount());
                        }
                    });
                }
            }else {//单聊
                accountList.add(toAccount);
            }
            TpnsSendForm tpnsSendForm = TpnsSendForm.builder()
                    .accountList(accountList)
                    .title(tpnsTitle)
                    .content(tpnsContent).build();
            this.tpnsService.pushApp(tpnsSendForm);*/
            if("TIMSoundElem".equals(msgType)){//音频不存
                return;
            }
            this.messageRepository.save(message);
        }
    }

}
